home *** CD-ROM | disk | FTP | other *** search
- ;Inttrpt.ASM
- ;Copyright (c) 1992 Jay Munro
- ;First published in PC Magazine June 16, 1992
-
- ;----------------------------------------------------------------------------
- ;Interrupt is a Call Interupt replacement for Visual Basic. Using the same
- ;register structure as the QuickBasic/BC7 InterruptX it allows the Visual
- ;Basic programmer access to DOS interrupts.
- ;If an error occurs, the function will return a value otherwise it returns
- ;a 0.
- ;
- ;Not all interrupts may be called. Some will just be ignored, as in
- ;early FCB functions or may cause UAEs.
- ;
- ; Syntax:
- ; Declare Function Interrupt% Lib "Labnotes.DLL" (Regs as Registers,
- ; Byval IntNum%)
- ; IntError% = Interrupt%(Regs, IntNum%)
- ;----------------------------------------------------------------------------
- ;Call Interrupt for Visual Basic
- ; TYPE RegType
- ; AX AS INTEGER
- ; BX AS INTEGER
- ; CX AS INTEGER
- ; DX AS INTEGER
- ; BP AS INTEGER ;unused on incoming registers
- ; SI AS INTEGER
- ; DI AS INTEGER
- ; Flags AS INTEGER
- ; DS AS INTEGER
- ; ES AS INTEGER
- ; END TYPE
-
- ; Outputs:
- ; If no errors occured:
- ; RegType = resulting values of register after interrupt was
- ; was executed.
- ; If errors did occur:
- ; function returns error (AX)
- ; RegType will remain unchanged
-
- .286P
-
- .Model Medium
- Include LabNotes.Inc
- Extrn AllocCStoDSAlias:Proc
- Extrn FreeSelector:Proc
- Public Interrupt
-
- User_Flgs Equ [BP-2h]
- User_DS Equ [BP-4h]
- Int_ES Equ [BP-6h]
- Int_DS Equ [BP-8h]
- Int_Flags Equ [BP-0Ah]
- Int_DI Equ [BP-0Ch]
- Int_SI Equ [BP-0Eh]
- Int_BP Equ [BP-10h] ;
- Int_DX Equ [BP-12h]
- Int_CX Equ [BP-14h]
- Int_BX Equ [BP-16h]
- Int_AX Equ [BP-18h]
- Old_SI Equ [BP-1Ah]
- Old_DI Equ [BP-1Ch]
- AliasCS Equ [BP-1Eh] ;aliased CS
- User_ES Equ [BP-20h]
- ReturnError Equ [BP-22h]
-
- .Code
-
- Interrupt Proc Far
- Push DS ;no DGroup, so ignore this code
- Pop AX
- Nop
- Inc BP
- Push BP
- Mov BP,SP
- Sub SP,22h ;set aside stack space
- Mov Old_SI,SI ;save DI,SI and DS
- Mov Old_DI,DI
- Mov User_DS,DS ; good ol DS
- Mov User_ES,ES ; save ES
- Mov Word Ptr ReturnError,0
- PushF
- Pop User_Flgs ;save Flags
- Lds SI,[BP+8] ;get pointer to users Type
- Lea DI,Int_AX ;get pointer to BP
- Mov CX,10 ;move 10 regs from users type
- Push SS ;point ES at SS
- Pop ES ;
- Cld ;move forward
- Rep MovSw ;move 10 regs into stack
- Push BP ;save BP to recover reg's after interrupt
-
- Push CS
- Call AllocCSToDSAlias ;make code seg writeable
- Mov AliasCS,AX ;save alloc'd CS for later
- Mov CX,[BP+6] ;get int value into CL
- Or CH,CH ;check for bad interrupt
- Jz @F ;int is between 0 and 255 - ok
- Jmp ErrorExit ;OOPS bad int
-
- @@:
- Push DS
- Mov DS,AX ;point DS at new selector
- Lea BX,IntNum
- Mov [BX],CL ;retread IntNum with new interrupt
- Lea BX, RegUInt
- Mov Word Ptr [BX],0BEBh ;set opcodes for Jmp Int_Return
-
- Cmp CL,25h ;interrupt 25h or 26?
- Jz @F ;yes, special handling
- Cmp CL,26h ; ditto
- Jnz NormalInt ;
- @@:
- Mov Word Ptr [BX],9090h ;nop out the jump
-
- NormalInt: ;now move input registers to actual registers
- Pop DS ;retread DS
- Mov AX,Int_Flags ;flag regester
- And AX,0111111010101b ;and out unused flags
- Push AX
- Mov AX,Int_AX
- Mov BX,Int_BX
- Mov CX,Int_CX
- Mov DX,Int_DX
- Mov SI,Int_SI
- Mov DI,Int_DI
-
- Cmp Word Ptr Int_ES,-1 ;are we doing ES?
- Jz @F
- Mov ES,Int_ES ;yes use it
- @@:
- Cmp Word Ptr Int_DS,-1 ;how about DS?
- Jz @F
- Mov DS,Int_DS ;use incoming
- @@:
- Cmp Word Ptr Int_BP,-1 ;how about BP?
- Jz @F
- Mov BP,Int_BP ;use incoming
- @@:
-
- ;---- Self modifying code (and they said it couldn't be done)
- Popf ;pop flags
- DB 0CDh ;interrupt number
- IntNum DB 0 ;goes here
-
- ;RegUInt: Jmp Short Int_Return
-
- RegUInt: DB 0EBh ;Jmp or not
- DB 0Bh ;
-
- Push AX
- Push BP
- Mov BP,SP
- Lahf ;load AX with flags
- Mov [BP+4],AH ;store flags into stack
- Pop BP
- Pop AX ;retrieve original AX
- PopF ;clear old flags
-
- Int_Return:
- Push BP ;save post Interrupt BP into temp
- Mov BP,SP ;Temp Frame is second word past this
- Mov BP,[BP+2h] ;get actual (old frame value)
- Jnc @F
- Mov ReturnError,AX ;assign error
- @@:
-
- ;Now assign back regs
- PushF
- Pop Int_Flags
- Push User_Flgs
- Popf ;retrieve incoming flags
- Mov Int_AX,AX ;save AX - ES back for type array
- Mov Int_BX,BX
- Mov Int_CX,CX
- Mov Int_DX,DX
- Mov AX,[BP-22] ;get temp BP that was saved
- Mov Int_BP,AX ;and into struct
- Mov Int_SI,SI
- Mov Int_DI,DI
- Mov Int_DS,DS
- Mov Int_ES,ES
-
- Push AliasCS ;free alias
- Call FreeSelector ;
-
- Lea SI,Int_AX
- Push SS ;point DS at stack where outgoing regs are
- Pop DS ; stored
- Les DI,[BP+8] ;get pointer to register type
- Cld ;forward moves
- Mov CX,10 ;move 10 reg's
- Rep MovSW ;move um
- Mov DI,Old_DI ;retrieve original DI & SI
- Mov SI,Old_SI
- Mov DS,User_DS ;retread DS
- Mov ES,User_ES ;retread ES
- Jmp Exit
- CritErrExit:
-
- ErrorExit:
- Pop BP
- Push AliasCS ;free alias
- Call FreeSelector ;
- Mov Word Ptr ReturnError,-1
-
- Exit:
- Mov AX, ReturnError
- Mov SP,BP ;reset SP
- Pop BP ;retrieve original BP
- Dec BP ;readjust BP
- Ret 6
-
- Interrupt EndP
- End
-